<!--
 * @Author: 半生瓜 1515706227@qq.com
 * @Date: 2024-04-21 17:20:21
 * @LastEditors: 半生瓜 1515706227@qq.com
 * @LastEditTime: 2024-05-28 14:10:29
 * @FilePath: \vue-element-plus-admin-mini\src\views\Login\components\LoginForm.vue
 * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
-->
<script setup lang="tsx">
import { reactive, ref, watch, onMounted, unref } from 'vue'
import { Form, FormSchema } from '@/components/Form'
import { useI18n } from '@/hooks/web/useI18n'
import { ElCheckbox, ElLink, ElMessage } from 'element-plus'
import { useForm } from '@/hooks/web/useForm'
import {
  loginApi,
  getRsaKey,
  getTestRoleApi,
  getAdminRoleApi,
  getRefreshToken,
  getuesrinfo
} from '@/api/login'
import { useAppStore } from '@/store/modules/app'
import { usePermissionStore } from '@/store/modules/permission'
import { useRouter } from 'vue-router'
import type { RouteLocationNormalizedLoaded, RouteRecordRaw } from 'vue-router'
import { UserType } from '@/api/login/types'
import { useValidator } from '@/hooks/web/useValidator'
import { useUserStore } from '@/store/modules/user'
import { BaseButton } from '@/components/Button'
import { Icon } from '@/components/Icon'
import { cloneDeep } from 'lodash-es'
import router from '@/router'
import { getSystem, saveSystem } from '@/api/System'

const { required } = useValidator()

const appStore = useAppStore()

const userStore = useUserStore()

const permissionStore = usePermissionStore()

const { currentRoute, addRoute, push } = useRouter()

const { t } = useI18n()

const rules = {
  username: [required()],
  password: [required()],
  authCode: [required()]
}

const schema = reactive<FormSchema[]>([
  {
    field: 'title',
    colProps: {
      span: 24
    },
    formItemProps: {
      slots: {
        default: () => {
          return (
            <h2 style="color: #409FFF;" class="text-3xl font-bold text-center w-[100%]">
              {t('login.login')}
            </h2>
          )
        }
      }
    }
  },
  {
    field: 'username',
    // value: 'admin',
    component: 'Input',
    colProps: {
      span: 24
    },
    componentProps: {
      placeholder: '请输入用户名',
      prefixIcon: <Icon icon="mdi:account" />
    }
  },
  {
    field: 'password',
    // value: 'admin',
    component: 'InputPassword',
    colProps: {
      span: 24
    },
    componentProps: {
      style: {
        width: '100%'
      },
      placeholder: '请输入密码',
      prefixIcon: <Icon icon="mdi:password-outline" />
    }
  },
  {
    field: 'authCode',
    // value: 'admin',
    component: 'InputPassword',
    colProps: {
      span: 24
    },
    componentProps: {
      style: {
        width: '100%'
      },
      placeholder: '请输入授权码',
      prefixIcon: <Icon icon="tdesign:secured" />
    }
  },
  {
    field: 'login',
    colProps: {
      span: 24
    },
    formItemProps: {
      slots: {
        default: () => {
          return (
            <>
              <div class="w-[100%]">
                <BaseButton
                  style="font-size: 1.3rem; height: 2.5rem; "
                  loading={loading.value}
                  type="primary"
                  class="w-[100%]"
                  onClick={signIn}
                >
                  {t('login.login')}
                </BaseButton>
              </div>
            </>
          )
        }
      }
    }
  }
])

const remember = ref(userStore.getRememberMe)

const initLoginInfo = () => {
  const loginInfo = userStore.getLoginInfo
  if (loginInfo) {
    const { username, password } = loginInfo
    setValues({ username, password })
  }
}
onMounted(() => {
  initLoginInfo()
})

const { formRegister, formMethods } = useForm()
const { getFormData, getElFormExpose, setValues } = formMethods

const loading = ref(false)

const redirect = ref<string>('')
watch(
  () => currentRoute.value,
  (route: RouteLocationNormalizedLoaded) => {
    redirect.value = route?.query?.redirect as string
  },
  {
    immediate: true
  }
)
//  加密
const encryptedData = function (publicKey, data) {
  // 新建JSEncrypt对象
  let encryptor = new JSEncrypt()
  // 设置公钥
  encryptor.setPublicKey(publicKey)
  // 加密数据
  return encryptor.encrypt(data)
}

// 登录
const signIn = async () => {
  const formRef = await getElFormExpose()
  await formRef?.validate(async (isValid) => {
    if (isValid) {
      loading.value = true

      const formData = await getFormData<UserType>()
      try {
        const res2 = await getRsaKey()

        let nweformData = cloneDeep(formData)

        nweformData.password = encryptedData(res2.data, formData.password)
        nweformData.username = encryptedData(res2.data, formData.username)
        nweformData.authCode = encryptedData(res2.data, formData.authCode)
        const res = await loginApi(nweformData)

        if (res) {
          // // 是否记住我
          // if (unref(remember)) {
          //   userStore.setLoginInfo({
          //     username: formData.username,
          //     password: formData.password
          //   })
          // } else {
          //   userStore.setLoginInfo(undefined)
          // }

          userStore.setRememberMe(unref(remember))
          userStore.setToken(res.data)
          userStore.setUserInfo(res.data)

          let a1 = {} as any
          let ressys = await getSystem()
          if (ressys) {
            ressys.data.map((item) => {
              if (item.configKey == 'jarVersion') {
                a1 = item
                a1.configValue = JSON.parse(a1.configValue)
                a1.configValue.manger = 'v1.0.0'
                a1.configValue = JSON.stringify(a1.configValue)

                saveSystem([a1]).then(() => {})
              }
            })
          }

          // 设置一个每2000毫秒执行一次的定时器
          let refreshtokentime = setInterval(function () {
            if (userStore.getToken) {
              getRefreshToken(userStore.getToken).then((res) => {
                userStore.setToken(res.data)
              })
            } else {
              clearInterval(refreshtokentime)
            }
          }, 480000)

          let res22 = await getuesrinfo()
          if (res22.code == 200) {
            localStorage.setItem('headimg', res22.data.headImg)
            localStorage.setItem('displayName', res22.data.displayName)
          }
          // 是否使用动态路由
          if (appStore.getDynamicRouter) {
            getRole()
          } else {
            await permissionStore.generateRoutes('static').catch(() => {})
            permissionStore.getAddRouters.forEach((route) => {
              addRoute(route as RouteRecordRaw) // 动态添加可访问路由表
            })
            permissionStore.setIsAddRouters(true)
            push({ path: redirect.value || permissionStore.addRouters[0].path })
          }
        }
      } finally {
        loading.value = false
      }
    }
  })
}

// 获取角色信息
const getRole = async () => {
  const formData = await getFormData<UserType>()
  const params = {
    roleName: formData.username
  }
  const res =
    appStore.getDynamicRouter && appStore.getServerDynamicRouter
      ? await getAdminRoleApi()
      : await getTestRoleApi(params)
  if (res) {
    if (res.data.length > 0) {
      console.log('kankan....', res.data)
      const routers = res.data || []
      userStore.setRoleRouters(routers)
      appStore.getDynamicRouter && appStore.getServerDynamicRouter
        ? await permissionStore.generateRoutes('server', routers).catch(() => {})
        : await permissionStore.generateRoutes('frontEnd', routers).catch(() => {})

      permissionStore.getAddRouters.forEach((route) => {
        addRoute(route as RouteRecordRaw) // 动态添加可访问路由表
      })
      permissionStore.setIsAddRouters(true)
      push({ path: redirect.value || permissionStore.addRouters[0].path })
    } else {
      userStore.setToken('')
      userStore.setUserInfo(undefined)
      userStore.setRoleRouters([])
      formData.username = ''
      formData.password = ''
      formData.authCode = ''
      ElMessage.error('暂无权限，请联系管理员')
    }
  }
}
</script>

<template>
  <Form
    :schema="schema"
    :rules="rules"
    label-position="top"
    hide-required-asterisk
    size="large"
    class="dark:(border-1 border-[var(--el-border-color)] border-solid)"
    @register="formRegister"
  />
</template>
